package org.musicmod.android.utils;

import java.lang.reflect.Method;

import android.media.audiofx.Visualizer;
import android.util.Log;

public class VisualizerWrapper {

	private Object mVisualizer;
	private OnDataCaptureListener mListener;

	public VisualizerWrapper(int audioSession) {
		try {
			mVisualizer = Class.forName("android.media.audiofx.Visualizer")
					.getConstructor(new Class[] { int.class })
					.newInstance(new Object[] { audioSession });
		} catch (Exception e) {
			Log.w("VisualizerWrapper", "Visualizer is not supported!");
		}
	}

	public interface OnDataCaptureListener {
		void onWaveFormDataCapture(VisualizerWrapper visualizer,
				byte[] waveform, int samplingRate);

		void onFftDataCapture(VisualizerWrapper visualizer, byte[] fft,
				int samplingRate);
	}

	public boolean getEnabled() {
		try {
			Method m = mVisualizer.getClass().getMethod("getEnabled",
					new Class[] {});
			return (Boolean) m.invoke(mVisualizer, new Object[] {});
		} catch (Exception e) {
		}
		return false;
	}

	public int setEnabled(boolean enabled) {
		try {
			Method m = mVisualizer.getClass().getMethod("setEnabled",
					new Class[] { boolean.class });
			return (Integer) m.invoke(mVisualizer, new Object[] { enabled });
		} catch (Exception e) {
		}
		return -1;
	}

	/**
	 * Returns the maximum capture rate for the callback capture method. This is
	 * the maximum value for the rate parameter of the
	 * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)}
	 * method.
	 * 
	 * @return the maximum capture rate expressed in milliHertz
	 */
	public static int getMaxCaptureRate(VisualizerWrapper visualizer) {
		try {
			return (Integer) Class.forName("android.media.audiofx.Visualizer")
					.getMethod("getMaxCaptureRate", new Class[] {})
					.invoke(visualizer, new Object[] {});
		} catch (Exception e) {
		}
		return -1;
	}

	public static int[] getCaptureSizeRange(VisualizerWrapper visualizer) {
		try {
			return (int[]) Class.forName("android.media.audiofx.Visualizer")
					.getMethod("getCaptureSizeRange", new Class[] {})
					.invoke(visualizer, new Object[] {});
		} catch (Exception e) {
		}
		return null;
	}

	public int setDataCaptureListener(OnDataCaptureListener listener, int rate,
			boolean waveform, boolean fft) {
		mListener = listener;
		try {
			Method m = mVisualizer
					.getClass()
					.getMethod(
							"setDataCaptureListener",
							new Class[] {
									Class.forName("android.media.audiofx.Visualizer$OnDataCaptureListener"),
									int.class, boolean.class, boolean.class });

			return (Integer) m.invoke(mVisualizer, new Object[] {
					new Visualizer.OnDataCaptureListener() {
						@Override
						public void onWaveFormDataCapture(
								Visualizer visualizer, byte[] waveform,
								int samplingRate) {
							mListener.onWaveFormDataCapture(
									VisualizerWrapper.this, waveform,
									samplingRate);
						}

						@Override
						public void onFftDataCapture(Visualizer visualizer,
								byte[] fft, int samplingRate) {
							mListener.onFftDataCapture(VisualizerWrapper.this,
									fft, samplingRate);

						}
					}, rate, waveform, fft });

		} catch (Exception e) {
		}
		return -1;
	}

	public int setCaptureSize(int size) {
		try {
			Method m = mVisualizer.getClass().getMethod("setCaptureSize",
					new Class[] { int.class });
			return (Integer) m.invoke(mVisualizer, new Object[] { size });
		} catch (Exception e) {
		}
		return -1;
	}

	public void release() {
		try {
			Method m = mVisualizer.getClass().getMethod("release",
					new Class[] {});
			m.invoke(mVisualizer, new Object[] {});
		} catch (Exception e) {
		}
	}
}